# -*- coding: utf-8 -*-
'''
@Software: PyCharm
@File    : normalize.py
@Author  : Bryan SHEN
@E-mail  : m18801919240_3@163.com
@Site    : Shanghai, China
@Time    : 2022-07-25
@Description: 
'''

import re
import json
# import jieba_fast as jieba
import jieba
from nltk.translate.meteor_score import meteor_score
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


class SkuNormalizeAndSimilarMatch(object):

    def __init__(self, match_column, product_type):

        self.column = match_column
        self.product_type = product_type
        self.load_data()

    def load_data(self):

        self.type_map = json.loads(open(BASE_DIR + "/libs/type_map.json", encoding="utf-8").read())
        # self.brands_map = json.loads(open(BASE_DIR + "/libs/brands_CN.json", encoding="utf-8").read())
        self.brands_map = json.loads(open(BASE_DIR + "/libs/brands_CN_new.json", encoding="utf-8").read())
        # self.category_map = json.loads(open(BASE_DIR + "/libs/category_map.json", encoding="utf-8").read())
        self.category_map = json.loads(open(BASE_DIR + "/libs/category_map_new.json", encoding="utf-8").read())

        # name_suffix = "/libs/" + self.product_type + "_sku.txt"
        self.normalized_skus = [line.strip() for line in open(BASE_DIR + "/libs/all_sku.txt", encoding="utf-8").readlines()]
        self.normalized_brand_sku_map = json.loads(open(BASE_DIR + "/libs/brand_sku_map.json", encoding="utf-8").read())

    def clean_text(self, text):

        text = str(text).lower().replace(" ", "").replace("-", "").replace("u先派样", "").replace("体验装", "").replace("u先试用", "").replace("体验组", "")

        text = re.sub("【.{0,20}?】", "", text)
        text = re.sub("（.{0,20}?）", "", text)
        text = re.sub("\[.{0,20}?\]", "", text)

        text = re.sub(r"([0-9]+ml)", "", text)
        text = re.sub(r"([0-9]+g)", "", text)
        text = re.sub(r"([0-9]+盒)", "", text)
        text = re.sub(r"([0-9]+片)", "", text)
        text = re.sub(r"([0-9]+瓶)", "", text)

        return text

    def normalize_single_type(self, text):

        text = self.clean_text(text)

        for product_suffix in self.category_map[self.type_map[self.product_type]] + ["礼盒", "套装"]:
            for brand in self.brands_map:
                for br_name in self.brands_map[brand]:
                    pattern = re.compile(br_name + r'.{0,15}?' + product_suffix)
                    matched_items = re.findall(pattern, str(text).lower())
                    if matched_items:
                        return matched_items[0].replace(br_name, brand), brand

        for product_suffix in self.category_map[self.type_map[self.product_type]]:
            pattern = re.compile(r'.{0,15}?' + product_suffix)
            matched_items = re.findall(pattern, str(text).lower())
            if matched_items:
                return matched_items[0], ""

        return "", ""

    def normalize_all_types(self, text):

        text = self.clean_text(text)

        for product_type in self.category_map:
            for product_suffix in self.category_map[product_type]:
                for brand in self.brands_map:
                    for br_name in self.brands_map[brand]:
                        pattern = re.compile(br_name + r'.{0,15}?' + product_suffix)
                        matched_items = re.findall(pattern, str(text).lower())
                        if matched_items:
                            return matched_items[0].replace(br_name, brand), product_type, brand

        for product_type in self.category_map:
            for product_suffix in self.category_map[product_type]:
                pattern = re.compile(r'.{0,15}?' + product_suffix)
                matched_items = re.findall(pattern, str(text).lower())
                if matched_items:
                    return matched_items[0], product_type, ""

        return "", "", ""

    def cut_fast(self, doc: str) -> list:

        return list(jieba.cut(doc))

    def get_meteor_sim(self, s1: str, s2: str):

        text1_cut, text2_cut = self.cut_fast(s1), self.cut_fast(s2)

        score = meteor_score([text1_cut], text2_cut)
        # score = meteor_score(text1_cut, text2_cut)

        return score

    def sim_rank(self, text, match_brand):

        dic = {}
        if match_brand and (match_brand in self.normalized_brand_sku_map):
            for sku in self.normalized_brand_sku_map[match_brand]:
                score = self.get_meteor_sim(text, sku)
                dic[sku] = score
        else:
            for sku in self.normalized_skus:
                score = self.get_meteor_sim(text, sku)
                dic[sku] = score

        return sorted(dic.items(), key=lambda x: x[1], reverse=True)[0]

    def run(self, item):

        if self.product_type != "all":
            normalized_sku, match_brand = self.normalize_single_type(item[self.column])
            product_type = self.product_type
        else:
            normalized_sku, product_type, match_brand = self.normalize_all_types(item[self.column])

        if normalized_sku:
            most_sililar_sku, ratio = self.sim_rank(normalized_sku, match_brand)
        else:
            most_sililar_sku, ratio = "", 0

        item["normalized_sku"] = normalized_sku
        item["match_brand"] = match_brand
        item["product_type"] = product_type
        item["most_sililar_sku"] = most_sililar_sku
        item["ratio"] = ratio

        return item


if __name__ == '__main__':

    item = {
        "text": " 城野医生（Dr.Ci:Labo） 50ml果酸100g精华水50ml 保湿收缩毛孔去黑头护肤水"
        # "text": " 【会员专享】3CE眼唇卸妆液宠爱礼包"
    }
    s = SkuNormalizeAndSimilarMatch("text", "all")

    print(s.run(item))
